﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Globalization;

namespace GoogleMaps
{
	/// <summary>
	/// A multi sided shape that can be filled with a specific color.
	/// </summary>
	public class GPolygon
	{
		/// <summary>
		/// Initializes a new instance of the GPolygon class.
		/// </summary>
		public GPolygon()
		{
			GEvents = new GEventCollection();
			GLatLngs = new GLatLngCollection();

			Clickable = true;
		}

		/// <summary>
		/// Renders the control by appending it to the stringbuilder that contains the JavaScript 
		/// for the related Google Map.
		/// </summary>
		/// <param name="js">A string builder containing the javascript that goes with the Google Map.</param>
		/// <param name="javaScriptVariableName">The namve of the JavaScript variable that is holding the map.</param>
		public void Render(StringBuilder js, string javaScriptVariableName)
		{
			string options = "";

			if (!Clickable)
				options = "clickable:false";

			if (options.Length > 0)
				options = String.Format(CultureInfo.InvariantCulture, ", {{{0}}}", options);

			if ((GEvents == null || GEvents.Count == 0) && String.IsNullOrEmpty(Id))
			{
				js.AppendFormat(CultureInfo.InvariantCulture,
					"{0}.addOverlay(new GPolygon({1}, {2}, {3}, {4}, {5}, {6}{7}));",
					javaScriptVariableName,
					GLatLngs.ToJavaScriptArray(),
					!String.IsNullOrEmpty(StrokeColor) ? StrokeColor.ToQuotedString(CultureInfo.InvariantCulture) : "null",
					StrokeWeight.HasValue ? StrokeWeight.Value.ToString(CultureInfo.InvariantCulture) : "null",
					StrokeOpacity.HasValue ? StrokeOpacity.Value.ToString(CultureInfo.InvariantCulture) : "null",
					!String.IsNullOrEmpty(FillColor) ? FillColor.ToQuotedString(CultureInfo.InvariantCulture) : "null",
					FillOpacity.HasValue ? FillOpacity.Value.ToString(CultureInfo.InvariantCulture) : "null",
					options);
			}
			else
			{
				if (String.IsNullOrEmpty(Id))
					throw new InvalidOperationException(Properties.Resources.GMarkerIdRequired);

				js.AppendFormat(CultureInfo.InvariantCulture,
					"var {0} = new GPolyline({1}, {2}, {3}, {4}, {5}, {6}{7});",
					Id,
					GLatLngs.ToJavaScriptArray(),
					!String.IsNullOrEmpty(StrokeColor) ? StrokeColor.ToQuotedString(CultureInfo.InvariantCulture) : "null",
					StrokeWeight.HasValue ? StrokeWeight.Value.ToString(CultureInfo.InvariantCulture) : "null",
					StrokeOpacity.HasValue ? StrokeOpacity.Value.ToString(CultureInfo.InvariantCulture) : "null",
					!String.IsNullOrEmpty(FillColor) ? FillColor.ToQuotedString(CultureInfo.InvariantCulture) : "null",
					FillOpacity.HasValue ? FillOpacity.Value.ToString(CultureInfo.InvariantCulture) : "null",
					options);

				foreach (GEvent ge in GEvents)
					ge.Render(js, Id);

				js.AppendFormat(CultureInfo.InvariantCulture, "{0}.addOverlay({1});", javaScriptVariableName, Id);
			}
		}

		/// <summary>
		/// Gets a collection of events that are wired to this polygon
		/// </summary>
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public GEventCollection GEvents { get; private set; }

		/// <summary>
		/// Gets a collection of GLatLngs that are associated with this polygon
		/// </summary>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Lngs"),
		PersistenceMode(PersistenceMode.InnerProperty)]
		public GLatLngCollection GLatLngs { get; private set; }

		/// <summary>
		/// Gets or sets the id of this share that will be used to build the javascript.
		/// </summary>
		public string Id { get; set; }

		/// <summary>
		/// Gets or sets a flag indicating that this polygon is clickable.
		/// </summary>
		public bool Clickable { get; set; }

		/// <summary>
		/// Gets or sets the color of the line that is used to draw the polygon.
		/// </summary>
		public string StrokeColor { get; set; }

		/// <summary>
		/// Gets or sets the width of the line that is used to draw the polygon.
		/// </summary>
		public int? StrokeWeight { get; set; }

		/// <summary>
		/// Gets or sets the opacity of the line that is used to draw the polygon.
		/// </summary>
		public int? StrokeOpacity { get; set; }

		/// <summary>
		/// Gets or sets the color that is used to fill the polygon.
		/// </summary>
		public string FillColor { get; set; }

		/// <summary>
		/// Gets or sets the opacity of the color that is used to fill the polygon.
		/// </summary>
		public decimal? FillOpacity { get; set; }
	}
}
